#ifndef __LIBVECTOR_H__
#define __LIBVECTOR_H__

#include <stdint.h>

// 颜色定义（用于彩色打印）
#define COLOR_RESET   "\033[0m"
#define COLOR_RED     "\033[31m"
#define COLOR_GREEN   "\033[32m"
#define COLOR_YELLOW  "\033[33m"
#define COLOR_BLUE    "\033[34m"
#define COLOR_MAGENTA "\033[35m"
#define COLOR_CYAN    "\033[36m"
#define COLOR_WHITE   "\033[37m"

// 工具函数声明（用于彩色输出）
// 打印信息并可指定颜色、是否退出程序等
void print_info(const char* msg, const char* color, bool exit_process,
                bool print_line, const char* file, int line);

// 成功信息（绿色）
#define success(msg) print_info((msg), COLOR_GREEN, false, false, NULL, 0)

// 警告信息（黄色）
#define warning(msg) print_info((msg), COLOR_YELLOW, false, false, NULL, 0)

// 错误信息（红色）并退出程序
#define error(msg) print_info((msg), COLOR_RED, true, true, __FILE__, __LINE__)

// 向量结构体定义
typedef struct vector_t {
    uint32_t size;       // 当前元素数量
    uint32_t capacity;   // 容量（可容纳的最大元素数量）
    void** array;        // 存储元素的指针数组
} vector_t;

/**
 * 创建指定初始容量的向量
 * @param vec 向量指针
 * @param cap 初始容量
 * @return 初始化后的向量指针
 */
vector_t *vec_new_cap(vector_t* vec, uint32_t cap);

/**
 * 创建默认容量（0）的向量
 * @param vec 向量指针
 * @return 初始化后的向量指针
 */
vector_t *vec_new(vector_t* vec);

/**
 * 在指定位置插入多个元素
 * @param vec 向量指针
 * @param index 插入位置索引
 * @param count 插入元素数量
 * @param ... 可变参数列表，待插入的元素
 */
void vec_insert_many_at_index(vector_t* vec, uint32_t index, uint32_t count, ...);

/**
 * 在指定位置插入单个元素
 * @param vec 向量指针
 * @param index 插入位置索引
 * @param value 待插入的元素
 */
void vec_insert_at_index(vector_t* vec, uint32_t index, void* value);

/**
 * 将源向量的所有元素追加到目标向量末尾
 * @param dest 目标向量
 * @param src 源向量
 */
void vec_push_back_vec(vector_t* dest, vector_t* src);

/**
 * 在向量末尾添加单个元素
 * @param vec 向量指针
 * @param value 待添加的元素
 */
void vec_push_back(vector_t* vec, void* value);

/**
 * 从指定位置移除多个元素
 * @param vec 向量指针
 * @param index 移除起始位置索引
 * @param count 移除元素数量
 * @param removed_items 用于存储被移除元素的向量
 * @return 存储被移除元素的向量指针
 */
vector_t* vec_remove_many_from_index(vector_t *vec, uint32_t index, int count,
                                     vector_t* removed_items);

/**
 * 从指定位置移除单个元素
 * @param vec 向量指针
 * @param index 移除位置索引
 * @return 被移除的元素
 */
void* vec_remove_from_index(vector_t* vec, uint32_t index);

/**
 * 移除并返回向量末尾的元素
 * @param vec 向量指针
 * @return 被移除的末尾元素
 */
void* vec_pop_back(vector_t* vec);

/**
 * 获取指定索引位置的元素
 * @param vec 向量指针
 * @param index 元素索引
 * @return 索引位置的元素
 */
void* vec_get(vector_t* vec, uint32_t index);

/**
 * 设置指定索引位置的元素
 * @param vec 向量指针
 * @param index 元素索引
 * @param value 新元素
 * @return 被替换的旧元素
 */
void* vec_set(vector_t* vec, uint32_t index, void* value);

/**
 * 获取向量的第一个元素
 * @param vec 向量指针
 * @return 第一个元素
 */
void* vec_front(vector_t* vec);

/**
 * 获取向量的最后一个元素
 * @param vec 向量指针
 * @return 最后一个元素
 */
void* vec_back(vector_t* vec);

/**
 * 获取向量当前元素数量
 * @param vec 向量指针
 * @return 元素数量
 */
uint32_t vec_size(vector_t* vec);

/**
 * 缩减向量容量以匹配实际元素数量（减少内存占用）
 * @param vec 向量指针
 */
void vec_shrink(vector_t* vec);

/**
 * 释放向量占用的内存
 * @param vec 向量指针
 */
void vec_free(vector_t* vec);

/**
 * 打印向量内容（彩色）
 * @param vec 向量指针
 * @param print_func 打印元素的回调函数
 * @param color 打印颜色
 */
void vec_print(vector_t* vec, void (*print_func)(void*), const char* color);
#endif // __LIBVECTOR_H__

#ifdef VECTOR_IMPLEMENTATION
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

/**
 * 计算向量容量变化后的新容量
 * @param vec 向量指针
 * @param change 容量变化量（正数表示增加，负数表示减少）
 * @return 新的容量
 */
static uint32_t changed_cap(vector_t *vec, int64_t change) {
    if (!change) {
        return vec->capacity;
    }
    // 处理容量增加的情况
    else if (change > 0) {
        // 如果当前容量足够，无需改变
        if (vec->size + change <= vec->capacity) {
            return vec->capacity;
        }

        uint64_t new_cap = vec->capacity;
        // 扩容策略：翻倍增长直到足够容纳新元素
        while(new_cap < vec->size + change) {
            if (new_cap == 1) {
                new_cap = 2;
                continue;
            }

            new_cap = (new_cap >> 1) << 2;  // 等价于 new_cap * 2

            if (new_cap == 0) {
                new_cap = 1;
            }
        }

        // 检查容量是否超过最大限制
        if (new_cap > UINT32_MAX) {
            error("向量大小超过最大限制");
        }

        return (uint32_t) new_cap;
    }
    // 处理容量减少的情况
    else {
        if (vec->size == 0) {
            error("向量大小至少为0");
        }
        if (vec->size + change == 0) {
            return 0;
        }

        int64_t new_cap = vec->capacity;
        // 缩容策略：减半直到刚好能容纳剩余元素
        while (new_cap >= (vec->size + change)) {
            if (new_cap == 0) {
                break;
            }

            new_cap = (new_cap >> 1);  // 等价于 new_cap / 2
        }

        // 调整到合适的容量
        if (new_cap == 0 && vec->size + change == 1) {
            new_cap = 1;
        } else {
            new_cap = new_cap << 1;  // 等价于 new_cap * 2
        }

        return (uint32_t)new_cap;
    }
}

/**
 * 调整向量内部数组的大小
 * @param vec 向量指针
 * @param cap_change 容量变化量
 */
static void resize_internal_array(vector_t *vec, int64_t cap_change) {
    int old_cap = vec->capacity;
    vec->capacity = changed_cap(vec, cap_change);

    // 如果新容量为0，释放内存
    if (vec->capacity == 0) {
        if (old_cap != 0) {
            free(vec->array);
        }

        vec->array = NULL;
        return;
    }

    // 重新分配内存
    vec->array = realloc(vec->array, sizeof(void*) * vec->capacity);
    if (!vec->array) {
        error("内存分配失败");
    }
}

/**
 * 工具函数：打印带颜色的信息
 * @param msg 消息内容
 * @param color 颜色代码
 * @param exit_process 是否退出程序
 * @param print_line 是否打印文件名和行号
 * @param file 文件名
 * @param line 行号
 */
void print_info(const char* msg, const char* color, bool exit_process,
                bool print_line, const char* file, int line) {
    if (color) {
        printf("%s", color);
    }

    if (print_line && file) {
        printf("[%s:%d] ", file, line);
    }

    printf("%s", msg);
    printf("%s\n", COLOR_RESET);  // 重置颜色

    if (exit_process) {
        exit(EXIT_FAILURE);
    }
}

vector_t* vec_new_cap(vector_t* vec, uint32_t cap) {
    vec->size = 0;
    vec->capacity = 0;
    vec->array = NULL;

    if (cap > 0) {
        resize_internal_array(vec, cap);
    }

    return vec;
}

vector_t* vec_new(vector_t* vec) {
    return vec_new_cap(vec, 0);
}

void vec_insert_many_at_index(vector_t* vec, uint32_t index , uint32_t count, ... ) {
    // 检查索引是否有效
    if (index > vec->size) {
        error("插入索引超出范围");
    }

    // 调整容量
    resize_internal_array(vec, count);

    // 移动元素为新元素腾出空间
    for (int i = vec->size - 1; i >= (int)index; i--) {
        vec->array[i + count] = vec->array[i];
    }

    // 处理可变参数并插入元素
    va_list args;
    va_start(args, count);

    for (uint32_t i = index; i < index + count; ++i) {
        vec->array[i] = va_arg(args, void*);
    }

    va_end(args);

    // 更新元素数量
    vec->size += count;
}

void vec_insert_at_index(vector_t* vec, uint32_t index, void* value) {
    vec_insert_many_at_index(vec, index, 1, value);
}

void vec_push_back_vec(vector_t* dest, vector_t* src) {
    if (!src || src->size == 0) {
        warning("源向量为空，无元素可添加");
        return;
    }

    // 调整目标向量容量
    resize_internal_array(dest, src->size);

    // 复制元素
    for (uint32_t i = 0; i < src->size; ++i) {
        dest->array[dest->size + i] = src->array[i];
    }

    // 更新目标向量元素数量
    dest->size += src->size;
}

void vec_push_back(vector_t* vec, void* value) {
    // 在末尾插入元素
    resize_internal_array(vec, 1);
    vec->array[vec->size] = value;
    vec->size++;
}

vector_t* vec_remove_many_from_index(vector_t *vec, uint32_t index, int count,
                                     vector_t* removed_items) {
    // 边界检查：防止越界
    if (index >= vec->size || count <= 0 || index + count > vec->size) {
        error("移除操作无效：索引或数量超出范围");
        return NULL;
    }

    // 保存要移除的元素
    for(uint32_t i = 0; i < (uint32_t)count; i++) {
        vec_push_back(removed_items, vec->array[index + i]);
    }

    // 移动剩余元素覆盖被移除的位置
    for(uint32_t i = index; i < vec->size - (uint32_t)count; i++) {
        vec->array[i] = vec->array[i + count];
    }

    // 调整容量并更新元素数量
    resize_internal_array(vec, -count);
    vec->size -= count;
    removed_items->size = count;

    return removed_items;
}

void* vec_remove_from_index(vector_t *vec, uint32_t index) {
    vector_t removed_item;
    vec_new(&removed_item);  // 初始化临时向量
    vec_remove_many_from_index(vec, index, 1, &removed_item);
    void* result = removed_item.array[0];
    vec_free(&removed_item);  // 释放临时向量内存
    return result;
}

void* vec_pop_back(vector_t* vec) {
    if (vec_size(vec) == 0) {  // 检查空向量
        error("无法从空向量中弹出元素");
        return NULL;
    }
    return vec_remove_from_index(vec, vec_size(vec) - 1);
}

void* vec_get(vector_t* vec, uint32_t index) {
    if (index >= vec_size(vec)) {
        error("访问超出向量范围");
    }

    return vec->array[index];
}

void *vec_set(vector_t *vec, uint32_t index, void* value) {
    if (index >= vec_size(vec)) {
        error("设置元素超出向量范围");
    }

    void *old_elem = vec->array[index];
    vec->array[index] = value;
    return old_elem;
}

void* vec_front(vector_t* vec) {
    if (vec_size(vec) == 0) {
        error("无法访问空向量的第一个元素");
    }
    return vec_get(vec, 0);
}

void* vec_back(vector_t * vec) {
    if (vec_size(vec) == 0) {
        error("无法访问空向量的最后一个元素");
    }
    return vec_get(vec, vec->size - 1);
}

uint32_t vec_size(vector_t* vec) {
    return vec->size;
}

void vec_shrink(vector_t *vec) {
    // 缩减容量到刚好容纳当前元素
    resize_internal_array(vec, -(int64_t)(vec->capacity - vec_size(vec)));
}

void vec_free(vector_t* vec) {
    free(vec->array);
    vec->array = NULL;
    vec->size = 0;
    vec->capacity = 0;
}

/**
 * 打印向量内容的实现
 * @param vec 要打印的向量
 * @param print_func 用于打印元素的回调函数（因元素类型未知）
 * @param color 打印使用的颜色
 */
void vec_print(vector_t* vec, void (*print_func)(void*), const char* color) {
    if (!vec) {
        error("向量指针为空");
        return;
    }

    if (!print_func) {
        error("未提供元素打印函数");
        return;
    }

    // 打印向量基本信息
    printf("%s向量信息: 大小=%u, 容量=%u, 元素=[",
           color ? color : "", vec->size, vec->capacity);

    // 打印每个元素
    for (uint32_t i = 0; i < vec->size; i++) {
        print_func(vec->array[i]);
        if (i != vec->size - 1) {
            printf(", ");
        }
    }

    // 重置颜色并结束打印
    printf("]%s\n", color ? COLOR_RESET : "");
}

#endif // VECTOR_IMPLEMENTATION
